﻿using System;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using System.Xml;

using WebDavProcessor.Constants;
using WebDavProcessor.Interfaces;
using WebDavProcessor.Resources;

namespace WebDavProcessor.Methods
{
    public class WebDavDelete : WebDavMethod
    {
        public WebDavDelete(IWebDavRequest webDavRequest)
            : base(webDavRequest)
        {
        }
        public WebDavDelete(string requestMethod, Uri requestUri, NameValueCollection requestHeaders, Stream requestInputStream)
            : base(requestMethod, requestUri, requestHeaders, requestInputStream)
        {
        }

        public override void ProcessRequest(IWebDavResponse webDavResponse, IWebDavResourceProvider resourceProvider)
        {
            if (this.Headers[WebDavHeaders.Depth] != null && this.Headers[WebDavHeaders.Depth] != WebDavHeaderValues.DepthValueInfinity)
            {
                WebDavMethod.SetError(webDavResponse, WebDavStatusCodes.BadRequest);
                return;
            }
            WebDavResource resource;
            if (!(resourceProvider is IWebDavIOProvider))
            {
                WebDavMethod.SetError(webDavResponse, WebDavStatusCodes.NotImplemented);
                return;
            }
            try
            {
                resource = (resourceProvider as IWebDavIOProvider).Delete(this.RequestUri.ToString());
                if (resource == null)
                {
                    WebDavMethod.SetError(webDavResponse, WebDavStatusCodes.NotImplemented);
                    return;
                }
                if (!(resource is WebDavResourceCollection))
                {
                    webDavResponse.StatusCode = resource.Status;
                    webDavResponse.StatusDescription = WebDavStatusDescriptions.GetDescription(resource.Status);
                    return;
                }
                WebDavResourceCollection resourceCollection = resource as WebDavResourceCollection;
                if (resourceCollection.Data.Count == 0)
                {
                    WebDavMethod.SetError(webDavResponse, WebDavStatusCodes.InternalServerError);
                    return;
                }

                MemoryStream stream = new MemoryStream();
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Encoding = Encoding.UTF8;
                XmlWriter writer = XmlWriter.Create(stream, settings);
                writer.WriteStartDocument();
                writer.WriteStartElement(WebDavXML.DefaultPrefix, WebDavXML.MultiStatus, WebDavXML.DefaultNameSpace);
                foreach (WebDavResource resourceItem in resourceCollection.Data)
                {
                    writer.WriteStartElement(WebDavXML.Response, WebDavXML.DefaultNameSpace);
                    writer.WriteStartElement(WebDavXML.Href, WebDavXML.DefaultNameSpace);
                    writer.WriteString(resourceItem.Path);
                    writer.WriteEndElement();
                    writer.WriteStartElement(WebDavXML.Status, WebDavXML.DefaultNameSpace);
                    writer.WriteString(WebDavXML.DefaultHttpVersion + " " + resourceItem.Status.ToString() + " " + WebDavStatusDescriptions.GetDescription(resourceItem.Status));
                    writer.WriteEndElement();
                    writer.WriteEndElement();
                }
                writer.WriteEndElement();
                writer.WriteEndDocument();
                writer.Flush();
                writer.Close();

                stream.Position = 0;

                webDavResponse.StatusCode = WebDavStatusCodes.MultiStatus;
                webDavResponse.StatusDescription = WebDavStatusDescriptions.MultiStatus;
                webDavResponse.Headers[WebDavHeaders.ContentType] = WebDavXML.DefaultContentType + "; " + WebDavXML.DefaultCharset;
                webDavResponse.Headers[WebDavHeaders.ContentLength] = stream.Length.ToString();
                webDavResponse.OutputStream = stream;
            }
            catch (WebDavException e)
            {
                WebDavMethod.SetError(webDavResponse, e.StatusCode);
                return;
            }
            catch (Exception)
            {
                WebDavMethod.SetError(webDavResponse, WebDavStatusCodes.InternalServerError);
                return;
            }
        }
    }
}
